/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.examples.modules.minicomposer; import java.io.*; import java.util.*; import javax.sound.sampled.*; public class LineInFromScore implements TargetDataLine { private AudioFormat format; private float sampleRate; private static class MyInputStream extends AudioInputStream { public MyInputStream (LineInFromScore me) throws IOException { super (me); Score s = me.s; frameLength = 0; float sampleRate = ComposerSettings.DEFAULT.getSampleRate (); for (int i = 0; i < s.getSize (); i++) frameLength += (int) (Score.DURATION_SECONDS[s.getDuration (i)] * sampleRate); } } public static AudioInputStream makeStream (InputStream is) throws IOException { return new MyInputStream (new LineInFromScore (is)); } /** * @associates LineListener */ private Set listeners; private int frame; private Score s; private int note; private int framesInNote; private int posInNote; private float frameToRadian; private boolean atEnd; private boolean isRest; public LineInFromScore (InputStream is) throws IOException { s = Score.parse (new InputStreamReader (is)); listeners = new HashSet (); frame = 0; note = -1; atEnd = false; sampleRate = ComposerSettings.DEFAULT.getSampleRate (); format = new AudioFormat (sampleRate, 8, 1, true, /* irrelevant */ false); update (); } public int read (byte[] b, int off, int len) { for (int i = 0; i < len; i++) { if (atEnd) return i; frame++; b[off + i] = isRest ? (byte) 0 : (byte) (127.0f * Math.sin (posInNote * frameToRadian)); if (++posInNote == framesInNote) update (); } return len; } private void update () { note++; if (note >= s.getSize ()) { atEnd = true; return; } int tone = s.getTone (note); int octave = s.getOctave (note); int dur = s.getDuration (note); framesInNote = (int) (Score.DURATION_SECONDS[dur] * sampleRate); posInNote = 0; if (tone == 0) { // Rest. isRest = true; } else { isRest = false; float hertz = (float) (Score.MIDDLE_C_HERTZ * Math.pow (Score.HALF_STEP, tone - Score.WHERE_IS_C_TONE) * Math.pow (2.0, octave - Score.WHERE_IS_MIDDLE_OCTAVE)); frameToRadian = 2.0f * (float) Math.PI / sampleRate * hertz; } } public int available () { if (atEnd) return 0; else return framesInNote - posInNote; } public synchronized void addLineListener (LineListener listener) { listeners.add (listener); } public synchronized void removeLineListener (LineListener listener) { listeners.remove (listener); } protected synchronized void fireEvent (LineEvent.Type type) { LineEvent ev = new LineEvent (this, type, frame); Iterator it = listeners.iterator (); while (it.hasNext ()) { LineListener listener = (LineListener) it.next (); listener.update (ev); } } public boolean isOpen () { return true; } public void open () throws LineUnavailableException { fireEvent (LineEvent.Type.OPEN); } public void open (AudioFormat format) throws LineUnavailableException { if (! format.equals (this.format)) throw new LineUnavailableException (); open (); } public void open (AudioFormat format, int bufferSize) throws LineUnavailableException { open (format); } public Control getControl (Control.Type control) { throw new IllegalArgumentException (); } public void flush () { } public void close () { fireEvent (LineEvent.Type.CLOSE); } public boolean isControlSupported (Control.Type control) { return false; } public Line.Info getLineInfo () { return new DataLine.Info (LineInFromScore.class, format, 1024); } public int getFramePosition () { return frame; } public boolean isActive () { return true; } public void drain () { } public boolean isRunning () { return true; } public void stop () { } public float getLevel () { return 1.0f; } public Control[] getControls () { return new Control[] { }; } public int getBufferSize () { return 1024; } public void start () { } public AudioFormat getFormat () { return format; } public long getMicrosecondPosition () { return (long) (1000000.0f * frame / sampleRate); } }